package com.example.xcService.pojo.tool;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.example.entity.*;
import com.example.pojo.enums.*;
import com.example.pojo.feign.AgentFeignService;
import com.example.pojo.rabbitmq.NoticeFanoutProduce;
import com.example.pojo.rabbitmq.OrderFanoutProduce;
import com.example.pojo.rabbitmq.QueryFanoutProduce;
import com.example.pojo.rabbitmq.RefundFanoutProduce;
import com.example.pojo.request.OperateRequest;
import com.example.pojo.request.OrderOperateRequest;
import com.example.pojo.response.Result;
import com.example.pojo.util.OrderHelpers;
import com.example.service.impl.AgentDeductionServiceImpl;
import com.example.service.impl.AgentProductServiceImpl;
import com.example.service.impl.ProductServiceImpl;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.pojo.response.CardData;
import com.example.service.*;
import com.example.service.impl.ThoroughfareServiceImpl;
import com.example.xcService.pojo.channels.ResultEnum;
import com.example.xcService.pojo.task.OrderTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class OrderTool {

    @Autowired
    IThoroughfareChannelService thoroughfareChannelService;

    @Autowired
    IChannelService channelService;

    @Autowired
    IChannelProductService channelProductService;

    @Autowired
    IApiInfoService apiInfoService;

    @Autowired
    IAgentOrderService agentOrderService;


    @Autowired
    IChannelOrderService channelOrderService;

    @Autowired
    ThoroughfareServiceImpl thoroughfareService;

    @Autowired
    IOrderPollingService pollingService;

    @Autowired
    IAgentService agentService;

    @Autowired
    IProductCardService cardService;

    @Autowired
    OrderTransactional orderTransactional;

    @Autowired
    IOrderRefundService refundService;

    @Autowired
    IRefundOrderService refundOrderService;

    @Autowired
    IRefundAutomoticService automoticService;

    @Autowired
    AgentFeignService feignService;

    @Autowired
    NoticeFanoutProduce orderFanoutProduce;

    @Autowired
    QueryFanoutProduce queryFanoutProduce;

    @Autowired
    ProductServiceImpl productService;

    @Autowired
    AgentProductServiceImpl agentProductService;

    @Autowired
    RefundFanoutProduce refundFanoutProduce;

    @Autowired
    OrderFanoutProduce submitProduce;

    @Autowired
    OrderHelpers orderHelpers;

    @Autowired
    AgentDeductionServiceImpl deductionService;


    /**
     * 生成签名
     *
     * @param map
     * @return
     */
    public static String getSignStr(Map<String, String> map) {
        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null && item.getKey() != "") {
                    String key = String.valueOf(item.getKey());
                    String val = String.valueOf(item.getValue());
                    if (StringUtils.hasLength(val)) {
                        sb.append(key + val);
                    }
                }
            }
            result = sb.toString();
        } catch (Exception e) {
            log.error("获取签名明文出错：", e);
            return null;
        }
        return result;
    }

    /**
     * Description:MD5工具生成token
     *
     * @param plainText
     * @return
     */
    public static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        StringBuilder md5code = new StringBuilder();
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes("UTF-8"));
            md5code = new StringBuilder(new BigInteger(1, secretBytes).toString(16));
            while (md5code.length() < 32) {
                md5code.insert(0, "0");
            }
        } catch (Exception ex) {
            log.error("md5加密异常：" + ex.getMessage(), ex);
        }
        return md5code.toString();
    }


    public void Deduction(AgentDeduction agentDeduction) {
        try {
            Agent agent = agentService.getById(agentDeduction.getAgentId());
            List<AgentOrder> list = JSONObject.parseArray(agentDeduction.getOrderInfo(), AgentOrder.class);
            AccountLog accountLog = new AccountLog();
            accountLog.setAgentName(agent.getAgentName());
            accountLog.setAgentId(agent.getId());
            accountLog.setBeforePrice(agent.getPrice());
            accountLog.setChangePrice(agentDeduction.getOrderTotalPrice());
            accountLog.setType(FundType.Deduction);
            accountLog.setLogType(FundType.Order);
            //代理扣款
            BigDecimal price = agent.getPrice().subtract(agentDeduction.getOrderTotalPrice());

            accountLog.setAfterPrice(price);
            accountLog.setAgentOrderNo(agentDeduction.getAgentOrderNo());
            agent.setPrice(price);
            OperateRequest request = new OperateRequest();
            request.setAgent(agent);
            request.setTotalPrice(agentDeduction.getOrderTotalPrice());
            request.setAccountLog(accountLog);
            request.setAgentOrderList(list);
            Result result = feignService.Operate(request);
            if (result.isSuccess()) {
                for (AgentOrder orderInfo : list) {
                    submitProduce.MakeOrder(orderInfo.getOrderCode());
                }
            } else {
                agentDeduction.setRetryCount(agentDeduction.getRetryCount() + 1);
                agentDeduction.setDeductionStatus(DeductionEnum.FAILED);
                agentDeduction.setErrMsg(result.getErrorMsg());
                deductionService.updateById(agentDeduction);
            }
        } catch (Exception ex) {
            agentDeduction.setRetryCount(agentDeduction.getRetryCount() + 1);
            agentDeduction.setDeductionStatus(DeductionEnum.WRONG);
            agentDeduction.setErrMsg("接口错误");
            deductionService.updateById(agentDeduction);
            log.error("代理商后台订单扣款出错" + agentDeduction.getAgentOrderNo() + ":", ex);
        }
    }


    public void Update(AgentOrder order) {
        try {
            //获取轮询数组
            LambdaQueryWrapper<OrderPolling> queryPolling = new LambdaQueryWrapper();
            queryPolling.eq(OrderPolling::getOrderCode, order.getOrderCode());
            queryPolling.eq(OrderPolling::getOrderStatus, PollingEnum.FAILED);
            List<OrderPolling> pollingList = pollingService.list(queryPolling);
            if (pollingList.size() == 0) {
                log.error(order.getOrderCode() + "pollingList为空");
                return;
            }
            OrderPolling polling = pollingList.get(pollingList.size() - 1);
            if (!PolymorphicType.Polling.equals(order.getPolymorphicType()) && !PolymorphicType.All.equals(order.getPolymorphicType())) {
                //单通道订单
                RefundOrder(order, polling);
            } else {
                //渠道列表
                LambdaQueryWrapper<ThoroughfareChannel> thoroughfareQuery = new LambdaQueryWrapper<>();
                thoroughfareQuery.eq(ThoroughfareChannel::getThoroughfareId, order.getThoroughfareId());
                List<ThoroughfareChannel> thoroughfareChannelList = thoroughfareChannelService.list(thoroughfareQuery);
                //渠道ID数组
                List<Integer> channelIds = thoroughfareChannelList.stream().map(ThoroughfareChannel::getChannelId).collect(Collectors.toList());

                //渠道产品列表为空
                if (channelIds.size() <= 0) {
                    order.setOrderStatus(OrderEnum.ERROR);
                    order.setErrMsg("无可用的渠道");
                    agentOrderService.updateById(order);
                    return;
                }

                //获取渠道产品列表
                LambdaQueryWrapper<ChannelProduct> channelProductQuery = new LambdaQueryWrapper<>();
                channelProductQuery.in(ChannelProduct::getChannelId, channelIds);
                channelProductQuery.eq(ChannelProduct::getProductStatus, ProductEnum.SALE);
                channelProductQuery.orderByAsc(ChannelProduct::getPrice);
                channelProductQuery.eq(ChannelProduct::getProductId, order.getProductId());
                List<ChannelProduct> channelProducts = channelProductService.list(channelProductQuery);

                channelProducts = channelProducts.stream().filter(a -> a.getPrice().compareTo(order.getAgentProductPrice()) <= 0).collect(Collectors.toList());
                //渠道产品列表为空
                if (channelProducts.size() <= 0) {
                    order.setOrderStatus(OrderEnum.ERROR);
                    order.setErrMsg("无可用的渠道");
                    agentOrderService.updateById(order);
                    return;
                }

                long failCount = pollingList.stream().filter(a -> a.getOrderStatus() == PollingEnum.FAILED).count();
                if (failCount >= channelProducts.size()) {
                    RefundOrder(order, polling);
                } else {
                    submitProduce.MakeOrder(order.getOrderCode());
                }
            }
        } catch (Exception ex) {
            log.error(order.getOrderCode() + "OrderTool.Update", ex);
            LambdaUpdateWrapper<AgentOrder> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(AgentOrder::getId, order.getId());
            wrapper.and(wrappers -> wrappers.eq(AgentOrder::getOrderStatus, OrderEnum.WAIT).or().eq(AgentOrder::getOrderStatus, OrderEnum.WAITREFUND)
                    .or().eq(AgentOrder::getOrderStatus, OrderEnum.REFUNDERROR).or().eq(AgentOrder::getOrderStatus, OrderEnum.ERROR));
            order.setOrderStatus(OrderEnum.REFUNDERROR);
            order.setErrMsg("退款出错");
            agentOrderService.update(order, wrapper);
        }
    }


    //单通道退款
    public void RefundOrder(AgentOrder order, OrderPolling polling) {
        try {
            ChannelOrder channelOrder = JSONObject.parseObject(polling.getOrderInfo(), ChannelOrder.class);
            //查看是否是多规格或者多数量订单,如果有成功的，主订单就设置成功，在err_msg备注，副订单成功，主订单失败
            if ((PolymorphicType.All.equals(order.getPolymorphicType()) || PolymorphicType.Polymorphic.equals(order.getPolymorphicType())) && (!order.getOrderCode().contains("MANY") && !order.getOrderCode().contains("GIVE"))) {
                LambdaQueryWrapper<AgentOrder> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.likeRight(AgentOrder::getOrderCode, order.getOrderCode());
                List<AgentOrder> agentOrders = agentOrderService.list(queryWrapper);
                long successCount = agentOrders.stream().filter(a -> a.getOrderCode().equals(order.getOrderCode()) == false && (OrderEnum.SUCCESS.equals(a.getOrderStatus()))).count();
                if (successCount >= 1) {
                    order.setOrderStatus(OrderEnum.SUCCESS);
                    order.setErrMsg("副订单成功，主订单失败");
                    orderTransactional.updateOrder(order);
                    orderFanoutProduce.OrderNotice(order.getId());
                    return;
                }
            }

            order.setOrderStatus(OrderEnum.FAILED);
            order.setErrMsg("充值失败");
            channelOrder.setOrderStatus(PollingEnum.FAILED);
            channelOrder.setGmtCreate(polling.getGmtCreate());
            channelOrder.setGmtModified(polling.getGmtModified());

            //查看是否是拆分订单
            if (order.getOrderCode().contains("MANY") || order.getOrderCode().contains("GIVE")) {
                order.setErrMsg("拆分订单,无需退款");
                orderTransactional.updateOrder(order, polling, channelOrder);
                return;
            }


            Agent agent = agentService.getById(order.getAgentId());
            BigDecimal price = agent.getPrice();
            AccountLog accountLog = new AccountLog();
            accountLog.setBeforePrice(agent.getPrice());
            price = price.add(order.getTotalPrice());
            agent.setPrice(price);

            accountLog.setAgentName(agent.getAgentName());
            accountLog.setAgentId(agent.getId());
            accountLog.setChangePrice(order.getTotalPrice());
            accountLog.setType(FundType.AddFunds);
            accountLog.setLogType(FundType.Order);
            accountLog.setAfterPrice(price);
            accountLog.setAgentOrderNo(order.getOrderCode());

            OrderOperateRequest request = new OrderOperateRequest();
            request.setAgentOrder(order);
            request.setChannelOrder(channelOrder);
            request.setAccountLog(accountLog);
            request.setAgent(agent);
            feignService.OrderOperate(request);
            orderFanoutProduce.OrderNotice(order.getId());
        } catch (Exception ex) {
            log.error(order.getOrderCode() + "OrderTool.RefundOrder", ex);
            LambdaUpdateWrapper<AgentOrder> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(AgentOrder::getId, order.getId());
            wrapper.and(wrappers -> wrappers.eq(AgentOrder::getOrderStatus, OrderEnum.WAIT).or().eq(AgentOrder::getOrderStatus, OrderEnum.WAITREFUND)
                    .or().eq(AgentOrder::getOrderStatus, OrderEnum.REFUNDERROR).or().eq(AgentOrder::getOrderStatus, OrderEnum.ERROR));
            order.setErrMsg("退款出错");
            order.setOrderStatus(OrderEnum.REFUNDERROR);
            agentOrderService.update(order, wrapper);
        }
    }

    public void Query(OrderPolling polling) {
        try {
            //渠道配置
            Channel channel = channelService.getById(polling.getChannelId());

            JSONObject apiConfig = JSONObject.parseObject(channel.getApiInfo());
            Map<String, Object> data = new HashMap<>();

            ApiInfo apiInfo = apiInfoService.getById(channel.getApiId());
            String className = apiInfo.getApiClass();

            Class cls = Class.forName(className);
            ChannelService service = (ChannelService) cls.newInstance();

            ChannelOrder channelOrder = JSONObject.parseObject(polling.getOrderInfo(), ChannelOrder.class);

            LambdaQueryWrapper<ChannelOrder> channelOrderQuery = new LambdaQueryWrapper<>();
            channelOrderQuery.eq(ChannelOrder::getOrderCode, polling.getOrderCode());
            ChannelOrder dbOrder = channelOrderService.getOne(channelOrderQuery);
            if (dbOrder != null) {
                channelOrder = dbOrder;
            }

            LambdaQueryWrapper<AgentOrder> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(AgentOrder::getOrderCode, polling.getOrderCode());
            AgentOrder order = agentOrderService.getOne(queryWrapper);

            data.put("AccountVal", order.getAccount());
            data.put("ChannelOrderCode", order.getOrderCode());
            data.put("SUPProductId", polling.getProductCode());
            data.put("BizOrderCode", polling.getBizOrderCode());
            data.put("CreatTime",order.getGmtCreate());
            //调用该方法并获取结果
            ChannelResult result = service.Query(apiConfig, data);
            String orderStatus = order.getOrderStatus();
            int channelOrderStatus = ResultEnum.WRONG;
            String errorMsg = result.errorMsg;

            if (result.isSuccess()) {
                log.info(order.getOrderCode() + "调用接口返回:" + JSONObject.toJSONString(result));
                if (result.code == ResultEnum.SUCCESS) {
                    orderStatus = OrderEnum.SUCCESS;
                    channelOrderStatus = PollingEnum.SUCCESS;
                    errorMsg = "充值成功";

                } else if (result.code == ResultEnum.FAILED) {
                    if (PolymorphicType.All.equals(order.getPolymorphicType()) || PolymorphicType.Polling.equals(order.getPolymorphicType())) {
                        orderStatus = OrderEnum.WAIT;
                        errorMsg = "轮询中";
                    } else {
                        orderStatus = OrderEnum.WAITREFUND;
                        errorMsg = "待退款";
                    }
                    channelOrderStatus = PollingEnum.FAILED;
                } else if (result.code == ResultEnum.IN_PROCESS) {
                    orderStatus = OrderEnum.IN_PROCESS;
                    channelOrderStatus = PollingEnum.UNDERWAY;
                    errorMsg = "充值中";
                }


                if (result.code == ResultEnum.SUCCESS) {
                    order.setOrderStatus(orderStatus);
                    polling.setOrderStatus(channelOrderStatus);
                    order.setErrMsg(errorMsg);
                    polling.setErrMsg(errorMsg);
                    if (result.data != null) {
                        order.setOrderInfo(JSONObject.toJSONString(result.data));
                    }
                    channelOrder.setOrderStatus(channelOrderStatus);
                    orderTransactional.updateOrder(order, polling, channelOrder);
                    orderFanoutProduce.OrderNotice(order.getId());
                } else if (result.code == ResultEnum.FAILED) {
                    polling.setErrMsg(result.errorMsg);
                    polling.setOrderStatus(channelOrderStatus);
                    order.setOrderStatus(orderStatus);
                    order.setErrMsg(errorMsg);
                    orderTransactional.updateOrder(order, polling);
                    if (PolymorphicType.All.equals(order.getPolymorphicType()) || PolymorphicType.Polling.equals(order.getPolymorphicType())) {
                        submitProduce.MakeOrder(order.getOrderCode());
                    } else {
                        refundFanoutProduce.OrderRefund(order.getId());
                    }
                }
            } else {
                order.setOrderStatus(orderStatus);
                polling.setOrderStatus(channelOrderStatus);
                polling.setErrMsg(result.errorMsg);
                order.setErrMsg(result.errorMsg);
                orderTransactional.updateOrder(order, polling);
            }
        } catch (Exception ex) {
            log.error(polling.getPollingId() + "OrderTool.Query出错", ex);
            polling.setErrMsg("查询接口出错");
            polling.setOrderStatus(PollingEnum.WRONG);
            pollingService.updateById(polling);
        }
    }


    //卡密
    public void Card(AgentOrder order) {
        try {
            Boolean OrderResult = orderTransactional.getAgentOrder(order.getId(), order.getVersion());
            if (!OrderResult) {
                return;
            }
            LambdaQueryWrapper<ProductCard> query = new LambdaQueryWrapper<>();
            query.eq(ProductCard::getProductId, order.getProductId());
            query.eq(ProductCard::getCardStatus, ProductCardEnum.Effective);
            query.last("ORDER BY RAND() limit " + order.getBuyNum());

            List<ProductCard> cardList = cardService.list(query);
            if (cardList.size() <= 0) {
                order.setErrMsg("库存不足");
                order.setOrderStatus(OrderEnum.ERROR);
                agentOrderService.updateById(order);
                return;
            }
            List<CardData> dataList = new ArrayList<>();


            for (ProductCard card : cardList) {
                CardData cardData = new CardData();
                cardData.setUrl(card.getCardUrl());
                cardData.setType(card.getType());
                cardData.setCode(card.getCardKey());
                cardData.setKey(card.getCardCode());
                cardData.setEffstart(card.getGmtEffective());
                cardData.setEffend(card.getGmtExpire());
                dataList.add(cardData);
                card.setAccount(order.getAccount());
                card.setCardStatus(ProductCardEnum.Used);
                card.setGmtUse(LocalDateTime.now());
                card.setOrderId(order.getId());
            }

            order.setOrderStatus(OrderEnum.SUCCESS);
            order.setOrderInfo(JSONObject.toJSONStringWithDateFormat(dataList, "yyyy-MM-dd", SerializerFeature.WriteMapNullValue));
            orderTransactional.UpdateCard(order, cardList);
            orderFanoutProduce.OrderNotice(order.getId());


        } catch (Exception ex) {
            log.error(order.getOrderCode() + "OrderTool.Card出错", ex);
            if (!"乐观锁修改失败".equals(ex.getMessage())) {
                LambdaUpdateWrapper<AgentOrder> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(AgentOrder::getId, order.getId());
                updateWrapper.and(wrappers -> wrappers.eq(AgentOrder::getOrderStatus, OrderEnum.UNDERWAY).or().eq(AgentOrder::getOrderStatus, OrderEnum.ERROR));
                updateWrapper.set(AgentOrder::getErrMsg, "获取卡密接口出错");
                updateWrapper.set(AgentOrder::getOrderStatus, "ERROR");
                updateWrapper.eq(AgentOrder::getVersion, order.getVersion());
                agentOrderService.update(updateWrapper);
            }
        }
    }

    //回调
    public void Notice(AgentOrder order) {
        try {
            Agent agent = agentService.getById(order.getAgentId());
            String url = agent.getCallbackUrl();
            if (!StringUtils.hasLength(url)) {
                order.setCallbackMsg("未绑定回调地址");
                order.setCallback(true);
                order.setGmtCallback(LocalDateTime.now());
                agentOrderService.updateById(order);
                return;
            }
            if (!OrderEnum.SUCCESS.equals(order.getOrderStatus()) && !OrderEnum.FAILED.equals(order.getOrderStatus())) {
                return;
            }

            long time = System.currentTimeMillis();
            Map dataparams = new LinkedHashMap<String, String>();
            dataparams.put("UserId", agent.getAgentCode());
            dataparams.put("BizType", "ECARD");
            dataparams.put("OrderNo", order.getOrderCode());
            dataparams.put("AccountVal", order.getAccount());
            dataparams.put("OrderStatus", order.getOrderStatus());
            dataparams.put("Time", String.valueOf(time));
            if (StringUtils.hasLength(order.getOrderInfo()) && OrderEnum.SUCCESS.equals(order.getOrderStatus())) {
                dataparams.put("ProductData", order.getOrderInfo());
            }
            String str = getSignStr(dataparams);

            String Sign = stringToMD5(str + agent.getSecretKey());

            dataparams.put("Sign", Sign);

            String responseContent = HttpTool.sendPost(url, dataparams);
            log.info(order.getOrderCode() + "回调订单返回：" + responseContent);
            JSONObject retobj = JSONObject.parseObject(responseContent);

            String code = retobj.getString("code");
            if ("0".equals(code)) {
                order.setCallback(true);
                order.setGmtCallback(LocalDateTime.now());
                order.setCallbackNum(order.getCallbackNum() + 1);
                agentOrderService.updateById(order);
            } else {
                order.setCallbackMsg(responseContent);
                order.setGmtCallback(LocalDateTime.now());
                order.setCallbackNum(order.getCallbackNum() + 1);
                agentOrderService.updateById(order);
            }

        } catch (Exception ex) {
            log.error(order.getOrderCode() + "OrderTool.Notice出错", ex);
            order.setCallbackMsg("回调接口出错");
            order.setCallbackNum(order.getCallbackNum() + 1);
            agentOrderService.updateById(order);
        }
    }

    public void Submit(AgentOrder order) {
        try {
            Boolean OrderResult = orderTransactional.getAgentOrder(order.getId(), order.getVersion());
            if (!OrderResult) {
                log.error(order.getOrderCode() + "乐观锁失败");
                return;
            }
            //渠道组ID
            Integer thoroughfareId = order.getThoroughfareId();
            if (thoroughfareId <= 0) {
                order.setOrderStatus(OrderEnum.ERROR);
                order.setErrMsg("未绑定渠道");
                agentOrderService.updateById(order);
                return;
            }
            Thoroughfare thoroughfare = thoroughfareService.getById(thoroughfareId);
            //先找到通道组，再找出通道列表，再找出通道列表中包含有产品的，产品价格最低的轮询提交
            //渠道列表
            LambdaQueryWrapper<ThoroughfareChannel> thoroughfareQuery = new LambdaQueryWrapper<>();
            thoroughfareQuery.eq(ThoroughfareChannel::getThoroughfareId, thoroughfareId);
            List<ThoroughfareChannel> thoroughfareChannelList = thoroughfareChannelService.list(thoroughfareQuery);
            //渠道ID数组
            List<Integer> channelIds = thoroughfareChannelList.stream().map(ThoroughfareChannel::getChannelId).collect(Collectors.toList());

            List<Integer> channelList = new ArrayList<>();

            //筛选渠道
            LambdaQueryWrapper<OrderPolling> pollingQuery = new LambdaQueryWrapper<>();
            pollingQuery.eq(OrderPolling::getOrderCode, order.getOrderCode());
            List<OrderPolling> pollingList = pollingService.list(pollingQuery);

            //渠道产品列表为空
            if (channelIds.size() <= 0) {
                order.setOrderStatus(OrderEnum.ERROR);
                order.setErrMsg("无可用的渠道");
                agentOrderService.updateById(order);
                return;
            }

            for (int id : channelIds) {
                Boolean isExist = pollingList.stream().anyMatch(d -> d.getChannelId() == id && (d.getOrderStatus() != PollingEnum.ERROR && d.getOrderStatus() != PollingEnum.SubmitERROR));
                if (!isExist) {
                    channelList.add(id);
                }
            }

            //渠道列表为空,退款
            if (channelList.size() == 0 && pollingList.size() >= 1) {
                Update(order);
                return;
            }


            //获取渠道产品列表
            LambdaQueryWrapper<ChannelProduct> channelProductQuery = new LambdaQueryWrapper<>();
            channelProductQuery.in(ChannelProduct::getChannelId, channelList);
            channelProductQuery.eq(ChannelProduct::getProductStatus, ProductEnum.SALE);
            channelProductQuery.eq(ChannelProduct::getProductId, order.getProductId());
            channelProductQuery.orderByAsc(ChannelProduct::getPrice);
            List<ChannelProduct> channelProducts = channelProductService.list(channelProductQuery);
            //过滤大于代理价格的渠道
            channelProducts = channelProducts.stream().filter(a -> a.getPrice().compareTo(order.getAgentProductPrice()) <= 0).collect(Collectors.toList());

            //渠道产品列表为空,退款
            if (channelProducts.size() == 0 && pollingList.size() >= 1) {
                Update(order);
                return;
            }


            //渠道产品列表为空
            if (channelProducts.size() <= 0) {
                LambdaUpdateWrapper<AgentOrder> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(AgentOrder::getId, order.getId());
                updateWrapper.eq(AgentOrder::getOrderStatus, OrderEnum.UNDERWAY);
                updateWrapper.set(AgentOrder::getErrMsg, "渠道组未配置产品");
                updateWrapper.set(AgentOrder::getOrderStatus, OrderEnum.ERROR);
                agentOrderService.update(updateWrapper);
                return;
            }


            //获取价格最低的
            ChannelProduct channelProduct = channelProducts.get(0);


            //渠道配置
            Channel channel = channelService.getById(channelProduct.getChannelId());

            /*
             * 未完成，订单轮询到相同渠道，不同订单号，现价段是唯一订单号
             * */

            //获取轮询数组
            LambdaQueryWrapper<OrderPolling> queryPolling = new LambdaQueryWrapper();
            queryPolling.eq(OrderPolling::getPollingId, order.getOrderCode() + channel.getId());

            OrderPolling polling = pollingService.getOne(queryPolling);


            //获取渠道订单
            ChannelOrder channelOrder = new ChannelOrder();
            channelOrder.setOrderCode(order.getOrderCode());
            channelOrder.setChannelId(channel.getId());
            channelOrder.setProductId(order.getProductId());
            channelOrder.setAgentId(order.getAgentId());
            channelOrder.setThoroughfareId(thoroughfareId);
            channelOrder.setProductName(order.getProductName());
            channelOrder.setChannelName(channel.getChannelName());
            channelOrder.setProductPrice(order.getProductPrice());
            channelOrder.setTotalPrice(channelProduct.getPrice());
            channelOrder.setOrderStatus(PollingEnum.UNDERWAY);
            channelOrder.setAccount(order.getAccount());
            channelOrder.setGmtCreate(LocalDateTime.now());
            channelOrder.setAgentName(order.getAgentName());
            channelOrder.setAccount(order.getAccount());
            channelOrder.setThoroughfareName(thoroughfare.getName());


            if (polling == null) {
                polling = new OrderPolling();
                polling.setChannelId(channel.getId());
                polling.setPollingId(order.getOrderCode() + channel.getId());
                polling.setOrderCode(order.getOrderCode());
                polling.setOrderInfo(JSONObject.toJSONString(channelOrder));
                polling.setChannelName(channel.getChannelName());
                polling.setProductCode(channelProduct.getProduceCode());
            } else {
                polling.setOrderInfo(JSONObject.toJSONString(channelOrder));
            }


            //反射类调用
            JSONObject apiConfig = JSONObject.parseObject(channel.getApiInfo());
            Map<String, Object> data = new HashMap<>();
            data.put("AccountVal", order.getAccount());
            data.put("ChannelOrderCode", order.getOrderCode());
            data.put("SUPProductId", channelProduct.getProduceCode());
            data.put("PurchasePrice", channelProduct.getPrice());
            data.put("ProductPrice", order.getProductPrice());
            data.put("AgentPrice", order.getTotalPrice());
            data.put("ProductName", order.getProductName());
            data.put("BuyNum", order.getBuyNum());
            ApiInfo apiInfo = apiInfoService.getById(channel.getApiId());
            String className = apiInfo.getApiClass();

            Class cls = Class.forName(className);
            ChannelService service = (ChannelService) cls.newInstance();


            //调用该方法并获取结果
            ChannelResult result = service.Submit(apiConfig, data);
            String orderStatus = order.getOrderStatus();
            int channelOrderStatus = ResultEnum.WRONG;
            String errorMsg = result.errorMsg;

            if (result.isSuccess()) {
                log.info(order.getOrderCode() + "调用接口返回:" + JSONObject.toJSONString(result));
                if (result.code == ResultEnum.SUCCESS) {
                    orderStatus = OrderEnum.SUCCESS;
                    channelOrderStatus = PollingEnum.SUCCESS;
                    errorMsg = "充值成功";

                } else if (result.code == ResultEnum.FAILED) {
                    if (PolymorphicType.All.equals(order.getPolymorphicType()) || PolymorphicType.Polling.equals(order.getPolymorphicType())) {
                        orderStatus = OrderEnum.WAIT;
                        errorMsg = "轮询中";
                    } else {
                        orderStatus = OrderEnum.WAITREFUND;
                        errorMsg = "待退款";
                    }
                    channelOrderStatus = PollingEnum.FAILED;
                } else if (result.code == ResultEnum.IN_PROCESS) {
                    orderStatus = OrderEnum.IN_PROCESS;
                    channelOrderStatus = PollingEnum.UNDERWAY;
                    errorMsg = "充值中";
                }


                if (result.code == ResultEnum.SUCCESS) {
                    order.setOrderStatus(orderStatus);
                    order.setErrMsg(errorMsg);
                    if (result.data != null) {
                        order.setOrderInfo(JSONObject.toJSONString(result.data));
                    }
                    if (StringUtils.hasLength(result.bizOrderCode)) {
                        polling.setBizOrderCode(result.bizOrderCode);
                    }
                    polling.setOrderStatus(channelOrderStatus);
                    polling.setErrMsg(errorMsg);
                    channelOrder.setOrderStatus(channelOrderStatus);
                    orderTransactional.saveOrder(order, polling, channelOrder);
                    orderFanoutProduce.OrderNotice(order.getId());
                } else if (result.code == ResultEnum.IN_PROCESS) {
                    if (StringUtils.hasLength(result.bizOrderCode)) {
                        polling.setBizOrderCode(result.bizOrderCode);
                    }
                    order.setOrderStatus(orderStatus);
                    order.setErrMsg(errorMsg);
                    polling.setOrderStatus(channelOrderStatus);
                    orderTransactional.saveOrder(order, polling);
                    queryFanoutProduce.OrderQuery(polling.getPollingId());
                } else if (result.code == ResultEnum.FAILED) {
                    polling.setOrderStatus(channelOrderStatus);
                    polling.setErrMsg(result.errorMsg);
                    order.setOrderStatus(orderStatus);
                    order.setErrMsg(errorMsg);
                    orderTransactional.saveOrder(order, polling);
                    if (PolymorphicType.All.equals(order.getPolymorphicType()) || PolymorphicType.Polling.equals(order.getPolymorphicType())) {
                        submitProduce.MakeOrder(order.getOrderCode());
                    } else {
                        refundFanoutProduce.OrderRefund(order.getId());
                    }
                }
            } else {
                polling.setOrderStatus(PollingEnum.SubmitERROR);
                polling.setErrMsg(result.errorMsg);
                order.setOrderStatus(OrderEnum.ERROR);
                order.setErrMsg(result.errorMsg);
                orderTransactional.saveOrder(order, polling);
            }

        } catch (Exception ex) {
            log.error(order.getOrderCode() + "OrderTool.Submit出错", ex);
            if (!"乐观锁修改失败".equals(ex.getMessage())) {
                LambdaUpdateWrapper<AgentOrder> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(AgentOrder::getId, order.getId());
                updateWrapper.and(wrappers -> wrappers.eq(AgentOrder::getOrderStatus, OrderEnum.UNDERWAY).or().eq(AgentOrder::getOrderStatus, OrderEnum.WAIT).or().eq(AgentOrder::getOrderStatus, OrderEnum.ERROR));
                updateWrapper.set(AgentOrder::getErrMsg, "轮询接口出错");
                updateWrapper.set(AgentOrder::getOrderStatus, OrderEnum.ERROR);
                updateWrapper.eq(AgentOrder::getVersion, order.getVersion());
                agentOrderService.update(updateWrapper);
            }
        }
    }

    public void OrderRefund(OrderRefund orderRefund) {
        try {

            LambdaQueryWrapper<AgentOrder> queryOrder = new LambdaQueryWrapper();
            queryOrder.eq(AgentOrder::getOrderCode, orderRefund.getOrderCode());
            AgentOrder order = agentOrderService.getOne(queryOrder);
            if (order == null) {
                orderRefund.setErrMsg("订单不存在");
                orderRefund.setOrderStatus(3);
                refundService.updateById(orderRefund);
                return;
            }

            LambdaQueryWrapper<OrderPolling> query = new LambdaQueryWrapper<>();
            query.eq(OrderPolling::getOrderCode, order.getOrderCode());
            List<OrderPolling> channelOrders = pollingService.list(query);
            if (channelOrders.size() <= 0) {
                orderRefund.setErrMsg("订单不存在");
                orderRefund.setOrderStatus(3);
                refundService.updateById(orderRefund);
                return;
            }
            channelOrders = channelOrders.stream().filter(a -> a.getOrderStatus() == 2).collect(Collectors.toList());
            if (channelOrders.size() <= 0) {
                orderRefund.setErrMsg("订单状态异常");
                orderRefund.setOrderStatus(3);
                refundService.updateById(orderRefund);
                return;
            }
            OrderPolling polling = channelOrders.get(0);

            //渠道配置
            Channel channel = channelService.getById(polling.getChannelId());

            LambdaQueryWrapper<ChannelProduct> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ChannelProduct::getChannelId, channel.getId());
            queryWrapper.eq(ChannelProduct::getProductId, order.getProductId());
            queryWrapper.last("limit 1");
            ChannelProduct channelProduct = channelProductService.getOne(queryWrapper);

            if (channelProduct == null) {
                orderRefund.setErrMsg("产品不存在");
                orderRefund.setOrderStatus(3);
                refundService.updateById(orderRefund);
                return;
            }
            Map<String, String> apiConfig = JSON.parseObject(channel.getApiInfo(), Map.class);
            Map<String, String> data = new HashMap<>();
            data.put("AccountVal", order.getAccount());
            data.put("ChannelOrderCode", order.getOrderCode());
            data.put("SUPProductId", channelProduct.getProduceCode());
            data.put("OrderInfo", order.getOrderInfo());

            ChannelResult result = new ChannelResult();
            result.code = -4;
            result.setSuccess(false);
            if (RefundEnum.KG.equals(orderRefund.getOrderType())) {
                result = RefundTool.DoAgentOrderKG(apiConfig, data);
            } else if (RefundEnum.MT.equals(orderRefund.getOrderType())) {
                result = RefundTool.DoAgentOrderMT(apiConfig, data);
            } else if (RefundEnum.SY.equals(orderRefund.getOrderType())) {
                result = RefundTool.DoAgentOrderSY(apiConfig, data);
            } else if (RefundEnum.ELM.equals(orderRefund.getOrderType()) || RefundEnum.ELMPACKAGE.equals(orderRefund.getOrderType())) {
                result = RefundTool.DoAgentOrderELM(apiConfig, data);
            } else if (RefundEnum.MTQ.equals(orderRefund.getOrderType())) {
                result = RefundTool.DoAgentOrderMTQ(apiConfig, data);
            }else if (RefundEnum.MTDC.equals(orderRefund.getOrderType())) {
                result =RefundTool.DoAgentOrderMTDC(apiConfig,data);
            }else if (RefundEnum.QQHY.equals(orderRefund.getOrderType())){
                result = RefundTool.DoAgentOrderQQHY(apiConfig, data);
            }else if (RefundEnum.HHSMW.equals(orderRefund.getOrderType())){
                result = RefundTool.DoAgentOrderHHSMW(apiConfig, data);
            }else {
                orderRefund.setErrMsg("无可用的退订");
                orderRefund.setOrderStatus(3);
                refundService.updateById(orderRefund);
                return;
            }
            if (result.isSuccess()) {
                log.info("调用接口返回:" + JSONObject.toJSONString(result));
                if (result.code == 99) {
                    orderRefund.setOrderStatus(2);
                    orderRefund.setErrMsg("退订成功");
                    refundService.updateById(orderRefund);

                } else if (result.code == -99) {
                    orderRefund.setOrderStatus(3);
                    orderRefund.setErrMsg(result.errorMsg);
                    refundService.updateById(orderRefund);
                }

            } else {
                orderRefund.setErrMsg(result.errorMsg);
                refundService.updateById(orderRefund);
            }


        } catch (Exception ex) {
            log.error("OrderTool.OrderRefund", ex);
            orderRefund.setErrMsg("轮询接口出错");
            refundService.updateById(orderRefund);
        }
    }


    public void OrderRefundAutoMoTic(RefundAutomotic orderRefund) {
        try {

            LambdaQueryWrapper<AgentOrder> queryOrder = new LambdaQueryWrapper();
            queryOrder.eq(AgentOrder::getOrderCode, orderRefund.getOrderCode());
            AgentOrder order = agentOrderService.getOne(queryOrder);
            if (order == null) {
                orderRefund.setErrMsg("订单不存在");
                orderRefund.setOrderStatus(4);
                automoticService.updateById(orderRefund);
                return;
            }

            LambdaQueryWrapper<OrderPolling> query = new LambdaQueryWrapper<>();
            query.eq(OrderPolling::getOrderCode, order.getOrderCode());
            List<OrderPolling> channelOrders = pollingService.list(query);
            if (channelOrders.size() <= 0) {
                orderRefund.setErrMsg("订单不存在");
                orderRefund.setOrderStatus(3);
                automoticService.updateById(orderRefund);
                return;
            }

            channelOrders = channelOrders.stream().filter(a -> a.getOrderStatus() == 2).collect(Collectors.toList());
            if (channelOrders.size() <= 0) {
                orderRefund.setErrMsg("订单状态异常");
                orderRefund.setOrderStatus(3);
                automoticService.updateById(orderRefund);
                return;
            }
            OrderPolling polling = channelOrders.get(0);

            //渠道配置
            Channel channel = channelService.getById(polling.getChannelId());

            LambdaQueryWrapper<ChannelProduct> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ChannelProduct::getChannelId, channel.getId());
            queryWrapper.eq(ChannelProduct::getProductId, order.getProductId());
            queryWrapper.last("limit 1");
            ChannelProduct channelProduct = channelProductService.getOne(queryWrapper);

            if (channelProduct == null) {
                orderRefund.setErrMsg("产品不存在");
                orderRefund.setOrderStatus(3);
                automoticService.updateById(orderRefund);
                return;
            }

            Map<String, String> apiConfig = JSON.parseObject(channel.getApiInfo(), Map.class);
            Map<String, String> data = new HashMap<>();
            data.put("AccountVal", order.getAccount());
            data.put("ChannelOrderCode", order.getOrderCode());
            data.put("SUPProductId", channelProduct.getProduceCode());

            ChannelResult result = new ChannelResult();
            result.code = -4;
            result.setSuccess(false);
            result = RefundTool.DoAgentOrderMT(apiConfig, data);
            if (result.isSuccess()) {
                log.info("调用接口返回:" + JSONObject.toJSONString(result));
                if (result.code == 99) {
                    orderRefund.setOrderStatus(2);
                    orderRefund.setErrMsg("退订成功");
                    automoticService.updateById(orderRefund);

                } else if (result.code == -99) {
                    orderRefund.setOrderStatus(3);
                    orderRefund.setErrMsg(result.errorMsg);
                    automoticService.updateById(orderRefund);
                }

            } else {
                orderRefund.setErrMsg(result.errorMsg);
                automoticService.updateById(orderRefund);
            }


        } catch (Exception ex) {
            log.error("OrderTool.OrderRefund", ex);
            orderRefund.setErrMsg("轮询接口出错");
            automoticService.updateById(orderRefund);
        }
    }


    public void OrderRefund1(RefundOrder orderRefund) {
        try {


            //渠道配置
            Channel channel = channelService.getById(16);


            Map<String, String> apiConfig = JSON.parseObject(channel.getApiInfo(), Map.class);
            Map<String, String> data = new HashMap<>();
            data.put("AccountVal", orderRefund.getPhone());
            data.put("ChannelOrderCode", orderRefund.getOrderCode());
            data.put("SUPProductId", orderRefund.getProductCode());

            ChannelResult result = new ChannelResult();
            result.code = -4;
            result.setSuccess(false);
            result = RefundTool.DoAgentOrderMT(apiConfig, data);
            if (result.isSuccess()) {
                log.info("调用接口返回:" + JSONObject.toJSONString(result));
                if (result.code == 99) {
                    orderRefund.setOrderStatus(2);
                    orderRefund.setErrMsg("退订成功");
                    refundOrderService.updateById(orderRefund);

                } else if (result.code == -99) {
                    orderRefund.setOrderStatus(3);
                    orderRefund.setErrMsg(result.errorMsg);
                    refundOrderService.updateById(orderRefund);
                }

            } else {
                orderRefund.setErrMsg(result.errorMsg);
                refundOrderService.updateById(orderRefund);
            }


        } catch (Exception ex) {
            log.error("OrderTool.OrderRefund", ex);
            orderRefund.setErrMsg("轮询接口出错");
            refundOrderService.updateById(orderRefund);
        }
    }
}
